package plugin;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;

import layout.TableLayout;

public class TrainDelayPane extends JPanel {
	private static final long serialVersionUID = 1L;
	protected HashMap<Integer, Train> zuglist;
	protected List<Train> zugpanellist = new LinkedList<Train>();
	protected GridPane gridpane;
	protected MainUI mainUI;
	private double[][] tbSize = new double[][] { { TableLayout.FILL }, // X
			{ TableLayout.MINIMUM, TableLayout.FILL } };
	protected JPanel train_content_pane;
	private boolean retry_repaint = false;
	private Timer refreshTimer;

	public TrainDelayPane(MainUI ui) {
		this.setLayout(new TableLayout(tbSize));
		TrainDescriptionsPane descriptions = new TrainDescriptionsPane();
		this.add(descriptions, "0,0");
		train_content_pane = new JPanel();
		train_content_pane.setLayout(new BoxLayout(train_content_pane,
				BoxLayout.PAGE_AXIS));
		JScrollPane scroller = new JScrollPane(train_content_pane,
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		scroller.getVerticalScrollBar().setUnitIncrement(15);
		
		this.add(scroller, "0,1");
		this.mainUI = ui;
		this.gridpane = new GridPane();
		this.addAutoRefresh();
	}

	protected void addAutoRefresh() {
		this.refreshTimer = new Timer(3000, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				refresh();
			}
		});
		refreshTimer.start();
	}

	protected void refresh() {
		try {
			update_panel();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected synchronized void push(HashMap<Integer, Train> zuglist) {
		this.zuglist = zuglist;
		repaint();
	}

	protected void repaintSuper() {
		try {
			super.revalidate();
			super.repaint();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public synchronized void repaint() {
		revalidate();
		super.repaint();
	}

	protected void update_panel() {
		do {
			try {
				if (zuglist != null) {
					for (final Train zug : this.zuglist.values()) {
						if (zug != null && zug.sichtbar && zug.steht) {
							if (!zugpanellist.contains(zug)) {
								SwingUtilities.invokeLater(new Runnable() {
									public void run() {
										TrainPane newOne = new TrainPane(zug,
												TrainDelayPane.this, gridpane);
										train_content_pane.add(newOne);
										gridpane.add(newOne
												.getAlternativePane());
										zugpanellist.add(zug);
										startFlashing(zug.getTrainPanel());
										gridpane.startFlashing(zug
												.getTrainPanel().getGridPane());
										int status = 0;
										if (zugpanellist != null
												&& zugpanellist.size() > 0) {
											status = 1;
											if (zug.verspaetung >= 0) {
												status = 2;
											}
										}
										if (mainUI != null)
											mainUI.setWarning(status);
									}
								});
							}
						}
					}
				}
				revalidate();
				super.repaint();
				if (MainUI.DEBUG) {
					if (this.retry_repaint)
						System.err
								.println("Queue wurde abgearbeitet, keine Fehler");
				}
			} catch (java.util.ConcurrentModificationException e) {
				if (MainUI.DEBUG) {
					if (!retry_repaint)
						System.err.println("TrainDelayPane: " + e
								+ ", in Queue verlagert");
				}
				if (MainUI.DEBUG) {
					if (retry_repaint)
						System.err.println("TrainDelayPane: Queue wartet");
				}
				this.retry_repaint = true;
			}
		} while (this.retry_repaint);
	}

	protected synchronized void remove(TrainPane t) {
		zugpanellist.remove(t.getZug());
		train_content_pane.remove(t);
	}

	protected void remove(TrainButtonPane t) {
		train_content_pane.remove(t);
	}

	protected JPanel getGridPane() {
		return gridpane;
	}

	protected void startRemoving(final TrainPane train) {
		SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
			@Override
			protected Boolean doInBackground() {
				try {
					for (int i = 1; i < 401; i++) {
						if (train.getZug().verspaetung >= 0) {
							train.setBackground(new Color(
									(int) (255 + ((255 - 255) / 400f * i)),
									(int) (115 + ((255 - 115) / 400f * i)),
									(int) (115 + ((255 - 115) / 400f * i))));
							train.setForeground(new Color(150, 150, 150));
						} else {
							train.setBackground(new Color(
									(int) (255 + ((255 - 255) / 400f * i)),
									(int) (240 + ((255 - 240) / 400f * i)),
									(int) (84 + ((255 - 84) / 400f * i))));
							train.setForeground(new Color(150, 150, 150));
						}
						// train.setForeground(new Color(255,255,255));
						Thread.sleep(10);
					}
				} catch (InterruptedException e) {

				}
				return true;
			}

			@Override
			protected void done() {
				remove(train);
			}
		};
		worker.execute();
	}

	protected void startFlashing(final TrainPane train) {
		SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
			@Override
			protected Boolean doInBackground() {
				try {
					boolean red = train.getZug().verspaetung >= 0;
					for (int j = 1; j < 5; j++) {
						for (int i = 1; i < 401; i++) {
							train.setBackground(red ? new Color(
									(int) (255 + ((255 - 255) / 400f * i)),
									(int) (115 + ((255 - 115) / 400f * i)),
									(int) (115 + ((255 - 115) / 400f * i)))
									: new Color(
											(int) (255 + ((255 - 255) / 400f * i)),
											(int) (240 + ((255 - 240) / 400f * i)),
											(int) (84 + ((255 - 84) / 400f * i))));
							Thread.sleep(1);
						}
						for (int i = 200; i > 0; i--) {
							train.setBackground(red ? new Color(
									(int) (255 + ((255 - 255) / 200f * i)),
									(int) (115 + ((255 - 115) / 200f * i)),
									(int) (115 + ((255 - 115) / 200f * i)))
									: new Color(
											(int) (255 + ((255 - 255) / 200f * i)),
											(int) (240 + ((255 - 240) / 200f * i)),
											(int) (84 + ((255 - 84) / 200f * i))));
							Thread.sleep(1);
						}
					}
				} catch (InterruptedException e) {

				} catch (Exception e) {
					System.err
							.println("EXCEPTION IN SWINGWORKER / TrainDelayPane / startFlashing"
									+ e);
				}
				return true;
			}

			@Override
			protected void done() {

			}
		};
		worker.execute();
	}

	public boolean hasElements() {		
		return zugpanellist.size()>0;
	}

}
